package com.gitee.wsl.common.chart.sample.funnel

import android.graphics.*
import com.gitee.wsl.android.ext.math.percent
import com.gitee.wsl.common.chart.ChartEnum
import com.gitee.wsl.common.chart.sample.XChart
import com.gitee.wsl.common.chart.sample.funnel.model.Funnel2Data
import com.gitee.wsl.ext.math.Dimensions
import com.gitee.wsl.math.Math
import com.gitee.wsl.jvm.math.add
import com.gitee.wsl.jvm.math.div
import com.gitee.wsl.jvm.math.mul
import com.gitee.wsl.jvm.math.sub

/**
 * @ClassName FunnelChart
 * @Description  漏斗图另一种风格，
 *      很久没画图了，在知乎上看了一个图(http://www.zhihu.com/question/31894603)，匆匆搞的.
 * @author XiongChuanLiang<br/>(xcl_168@aliyun.com)
 *
 */
class FunnelChart2: XChart() {

     val paint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)
     val labelPaint: Paint =  Paint(Paint.ANTI_ALIAS_FLAG).apply {
         color = Color.BLACK
     }
     val dataSet= mutableListOf<Funnel2Data> ()
     var bgColor = Color.WHITE
    

    override fun getType(): ChartEnum.ChartType {
        return ChartEnum.ChartType.FUNNEL
    }

    protected fun drawPlot(canvas: Canvas) {
        if (dataSet.size == 0) return
        val fHalfTopWidth: Float = Math.div(bodyViewport.width, 5f)
        val funnelTopWidth: Float = Math.mul(fHalfTopWidth, 2f)
        val funnelTopStartX: Float = Math.sub(bodyViewport.centerX, fHalfTopWidth)
        val funnelTopStopX: Float = Math.add(bodyViewport.centerX, fHalfTopWidth)

        //打底
        val cPath = Path()
        cPath.moveTo(bodyViewport.left, bodyViewport.bottom)
        cPath.lineTo(bodyViewport.right, bodyViewport.bottom)
        cPath.lineTo(funnelTopStopX, bodyViewport.top)
        cPath.lineTo(funnelTopStartX, bodyViewport.top)
        cPath.close()
        paint.style = Paint.Style.FILL
        paint.color = dataSet[0].color
        canvas.drawPath(cPath, paint)
        val lstTop: MutableList<PointF> = ArrayList()
        val lstCenter: MutableList<PointF> = ArrayList()
        val lstRight: MutableList<PointF> = ArrayList()
        val dataSize = dataSet.size
        var fx = funnelTopStartX //MathExt.sub(plotArea.getCenterX() , fHalfTopWidth );
        var fy: Float = bodyViewport.top

        // 依chartPercentData 得到上面的线的比例
        for (i in 0 until dataSize) {
            fx = Math.add(fx, Math.mul(funnelTopWidth, dataSet[i].percentData))
            lstTop.add(PointF(fx, fy))
        }

        // 中间控制点位置
        fy = bodyViewport.bottom
        val fSpaddWidth: Float = Math.div(Math.sub(bodyViewport.width, funnelTopWidth), 2f)
        var rx: Float
        var leftX: Float
        var rightX: Float
        var cx: Float
        for (i in 0 until dataSize) {
            fy = Math.sub(fy, Math.mul(bodyViewport.height, dataSet[i].baseData))
            rx = Math.mul(fSpaddWidth, Math.sub(1f, Math.div(fy, bodyViewport.height)))
            leftX = bodyViewport.left + rx
            rightX = bodyViewport.right - rx
            cx = leftX + (rightX - leftX) * dataSet[i].percentData
            lstCenter.add(PointF(cx, fy))
        }

        // 右边结束位置及标签位置
        val lstLabel: MutableList<Float> = ArrayList()
        var labelY = 0f
        val labelX: Float = Math.add(funnelTopStopX, Math.div(fSpaddWidth, 2f))
        fy = bodyViewport.bottom
        for (i in 0 until dataSize) {
            fy = Math.sub(fy, Math.mul(bodyViewport.height, dataSet[i].percentData))
            lstRight.add(PointF(bodyViewport.right, fy))
            if (i == 0) {
                lstLabel.add(Math.sub(bodyViewport.bottom, Math.div(Math.sub(bodyViewport.bottom, fy), 2f)))
            } else {
                labelY = Math.div(Math.sub(fy, lstRight[i - 1].y), 2f)
                labelY = Math.sub(fy, labelY)
                lstLabel.add(labelY)
            }
        }
        ////////////////////////////	

        //填充区域
        val bezierPath = Path()
        for (i in lstTop.indices) {
            if (i + 1 >= lstTop.size) continue
            paint.setColor(dataSet[i + 1].color)
            bezierPath.moveTo(lstTop[i].x, lstTop[i].y)
            val ctl2 = Dimensions.percent(lstTop[i], 0.7f, lstCenter[i], 0.5f)
            bezierPath.quadTo(ctl2.x, ctl2.y, lstCenter[i].x, lstCenter[i].y)
            val ctl3 = Dimensions.percent(lstCenter[i], 0.1f, lstRight[i], 0.9f)
            bezierPath.quadTo(ctl3.x, ctl3.y, lstRight[i].x, lstRight[i].y)
            bezierPath.lineTo(funnelTopStopX, bodyViewport.top)
            bezierPath.close()
            canvas.drawPath(bezierPath, paint)
            bezierPath.reset()
        }

        // 盖掉多出的区域.(本来有更好的算位置的方法，不小心删了，没心情再搞了)
        //paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        cPath.reset()
        cPath.moveTo(bodyViewport.right, bodyViewport.bottom)
        cPath.lineTo(bodyViewport.right, bodyViewport.top)
        cPath.lineTo(funnelTopStopX, bodyViewport.top)
        cPath.close()
        paint.color = bgColor
        canvas.drawPath(cPath, paint)
        cPath.reset()
        cPath.moveTo(bodyViewport.left, bodyViewport.top)
        cPath.lineTo(funnelTopStartX, bodyViewport.top)
        cPath.lineTo(bodyViewport.left, bodyViewport.bottom)
        cPath.close()
        canvas.drawPath(cPath, paint)
        //画上标签
        for (i in lstLabel.indices) {
            canvas.drawText(dataSet[i].label, labelX, lstLabel[i], labelPaint)
        }
        ////////////////////////////
    }


    override fun readerBackground(canvas: Canvas) {
        super.readerBackground(canvas)
        canvas.drawColor(bgColor)

        //画Plot Area背景
        bodyViewport.render(canvas)
    }


    override fun renderBody(canvas: Canvas): Boolean {

        super.renderBody(canvas)

            //计算主图表区范围
            //calcPlotRange()

         //绘制图表
         drawPlot(canvas)
        return true
    }

    /////////////////////
    
}